<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>Using Picasa Web Albums - Zend Framework Manual</title>

    <link href="../css/shCore.css" rel="stylesheet" type="text/css" />
    <link href="../css/shThemeDefault.css" rel="stylesheet" type="text/css" />
    <link href="../css/styles.css" media="all" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Zend Framework</h1>
<h2>Programmer's Reference Guide</h2>
<ul>
    <li><a href="../en/zend.gdata.photos.html">Inglês (English)</a></li>
    <li><a href="../pt-br/zend.gdata.photos.html">Português Brasileiro (Brazilian Portuguese)</a></li>
</ul>
<table width="100%">
    <tr valign="top">
        <td width="85%">
            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="zend.gdata.gbase.html">Using Google Base</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="zend.gdata.html">Zend_Gdata</a></span><br />
                        <span class="home"><a href="manual.html">Programmer's Reference Guide</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="zend.gdata.youtube.html">Using the YouTube Data API</a></div>
                    </td>
                </tr>
            </table>
<hr />
<div id="zend.gdata.photos" class="section"><div class="info"><h1 class="title">Using Picasa Web Albums</h1></div>
    

    <p class="para">
        Picasa Web Albums is a service which allows users to maintain albums of
        their own pictures, and browse the albums and pictures of others.
        The <acronym class="acronym">API</acronym> offers a programmatic interface to this service, allowing
        users to add to, update, and remove from their albums, as well as
        providing the ability to tag and comment on photos.
    </p>

    <p class="para">
        Access to public albums and photos is not restricted by account,
        however, a user must be logged in for non-read-only access.
    </p>

    <p class="para">
        For more information on the <acronym class="acronym">API</acronym>, including
        instructions for enabling <acronym class="acronym">API</acronym> access, refer to the <a href="http://code.google.com/apis/picasaweb/overview.html" class="link external">&raquo; Picasa
        Web Albums Data <acronym class="acronym">API</acronym> Overview</a>.
    </p>

    <blockquote class="note"><p><b class="note">Note</b>: <span class="info"><b>Authentication</b><br /></span>
        

        <p class="para">
            The <acronym class="acronym">API</acronym> provides authentication via AuthSub (recommended)
            and ClientAuth. <acronym class="acronym">HTTP</acronym> connections must be authenticated for write
            support, but non-authenticated connections have read-only access.
        </p>
    </p></blockquote>

    <div class="section" id="zend.gdata.photos.connecting"><div class="info"><h1 class="title">Connecting To The Service</h1></div>
        

        <p class="para">
            The Picasa Web Albums <acronym class="acronym">API</acronym>, like all GData <acronym class="acronym">API</acronym>s, is
            based off of the Atom Publishing Protocol (APP), an <acronym class="acronym">XML</acronym> based format
            for managing web-based resources. Traffic between a client and the servers occurs over
            <acronym class="acronym">HTTP</acronym> and allows for both authenticated and unauthenticated
            connections.
        </p>

        <p class="para">
            Before any transactions can occur, this connection needs to be made. Creating a
            connection to the Picasa servers involves two steps: creating an <acronym class="acronym">HTTP</acronym>
            client and binding a <span class="classname">Zend_Gdata_Photos</span>
            service instance to that client.
        </p>

        <div class="section" id="zend.gdata.photos.connecting.authentication"><div class="info"><h1 class="title">Authentication</h1></div>
            

            <p class="para">
                The Google Picasa <acronym class="acronym">API</acronym> allows access to both public and private
                photo feeds. Public feeds do not require authentication, but are read-only and offer
                reduced functionality. Private feeds offers the most complete functionality but
                requires an authenticated connection to the Picasa servers. There are three
                authentication schemes that are supported by Google Picasa :
            </p>

            <ul class="itemizedlist">
                <li class="listitem">
                    <p class="para">
                        <b class="firstterm">ClientAuth</b>
                        provides direct username/password authentication to the
                        Picasa servers. Since this scheme requires that users
                        provide your application with their password, this
                        authentication is only recommended when other
                        authentication schemes are insufficient.
                    </p>
                </li>

                <li class="listitem">
                    <p class="para">
                        <b class="firstterm">AuthSub</b>
                        allows authentication to the Picasa servers via a
                        Google proxy server. This provides the same level of
                        convenience as ClientAuth but without the security
                        risk, making this an ideal choice for web-based
                        applications.
                    </p>
                </li>
            </ul>

            <p class="para">
                The
                <span class="classname">Zend_Gdata</span>
                library provides support for both authentication schemes.
                The rest of this chapter will assume that you are familiar the
                authentication schemes available and how to create an
                appropriate authenticated connection. For more information,
                please see section the
                <a href="zend.gdata.introduction.html#zend.gdata.introduction.authentication" class="link">Authentication section</a>
                of this manual or the <a href="http://code.google.com/apis/gdata/auth.html" class="link external">&raquo; Authentication Overview in the
                    Google Data <acronym class="acronym">API</acronym> Developer&#039;s Guide</a>.
            </p>
        </div>

        <div class="section" id="zend.gdata.photos.connecting.service"><div class="info"><h1 class="title">Creating A Service Instance</h1></div>
            

            <p class="para">
                In order to interact with the servers, this library provides the
                <span class="classname">Zend_Gdata_Photos</span> service class. This class provides a common
                interface to the Google Data and Atom Publishing Protocol models and assists in
                marshaling requests to and from the servers.
            </p>

            <p class="para">
                Once deciding on an authentication scheme, the next step is to create an instance of
                <span class="classname">Zend_Gdata_Photos</span>. The class constructor takes an instance of
                <span class="classname">Zend_Http_Client</span> as a single argument. This provides an
                interface for AuthSub and ClientAuth authentication, as both of these require
                creation of a special authenticated <acronym class="acronym">HTTP</acronym> client. If no arguments
                are provided, an unauthenticated instance of <span class="classname">Zend_Http_Client</span>
                will be automatically created.
            </p>

            <p class="para">
                The example below shows how to create a service class using ClientAuth
                authentication:
            </p>

            <pre class="programlisting brush: php">
// Parameters for ClientAuth authentication
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$user = &quot;sample.user@gmail.com&quot;;
$pass = &quot;pa$$w0rd&quot;;

// Create an authenticated HTTP client
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);

// Create an instance of the service
$service = new Zend_Gdata_Photos($client);
</pre>


            <p class="para">
                A service instance using AuthSub can be created in a similar, though slightly more
                lengthy fashion:
            </p>

            <pre class="programlisting brush: php">
session_start();

/**
 * Returns the full URL of the current page, based upon env variables
 *
 * Env variables used:
 * $_SERVER[&#039;HTTPS&#039;] = (on|off|)
 * $_SERVER[&#039;HTTP_HOST&#039;] = value of the Host: header
 * $_SERVER[&#039;SERVER_PORT&#039;] = port number (only used if not http/80,https/443)
 * $_SERVER[&#039;REQUEST_URI&#039;] = the URI after the method of the HTTP request
 *
 * @return string Current URL
 */
function getCurrentUrl()
{
    global $_SERVER;

    /**
     * Filter php_self to avoid a security vulnerability.
     */
    $php_request_uri = htmlentities(substr($_SERVER[&#039;REQUEST_URI&#039;], 0,
    strcspn($_SERVER[&#039;REQUEST_URI&#039;], &quot;\n\r&quot;)), ENT_QUOTES);

    if (isset($_SERVER[&#039;HTTPS&#039;]) &amp;&amp; strtolower($_SERVER[&#039;HTTPS&#039;]) == &#039;on&#039;) {
        $protocol = &#039;https://&#039;;
    } else {
        $protocol = &#039;http://&#039;;
    }
    $host = $_SERVER[&#039;HTTP_HOST&#039;];
    if ($_SERVER[&#039;SERVER_PORT&#039;] != &#039;&#039; &amp;&amp;
        (($protocol == &#039;http://&#039; &amp;&amp; $_SERVER[&#039;SERVER_PORT&#039;] != &#039;80&#039;) ||
        ($protocol == &#039;https://&#039; &amp;&amp; $_SERVER[&#039;SERVER_PORT&#039;] != &#039;443&#039;))) {
            $port = &#039;:&#039; . $_SERVER[&#039;SERVER_PORT&#039;];
    } else {
        $port = &#039;&#039;;
    }
    return $protocol . $host . $port . $php_request_uri;
}

/**
 * Returns the AuthSub URL which the user must visit to authenticate requests
 * from this application.
 *
 * Uses getCurrentUrl() to get the next URL which the user will be redirected
 * to after successfully authenticating with the Google service.
 *
 * @return string AuthSub URL
 */
function getAuthSubUrl()
{
    $next = getCurrentUrl();
    $scope = &#039;http://picasaweb.google.com/data&#039;;
    $secure = false;
    $session = true;
    return Zend_Gdata_AuthSub::getAuthSubTokenUri($next, $scope, $secure,
        $session);
}

/**
 * Returns a HTTP client object with the appropriate headers for communicating
 * with Google using AuthSub authentication.
 *
 * Uses the $_SESSION[&#039;sessionToken&#039;] to store the AuthSub session token after
 * it is obtained. The single use token supplied in the URL when redirected
 * after the user succesfully authenticated to Google is retrieved from the
 * $_GET[&#039;token&#039;] variable.
 *
 * @return Zend_Http_Client
 */
function getAuthSubHttpClient()
{
    global $_SESSION, $_GET;
    if (!isset($_SESSION[&#039;sessionToken&#039;]) &amp;&amp; isset($_GET[&#039;token&#039;])) {
        $_SESSION[&#039;sessionToken&#039;] =
            Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET[&#039;token&#039;]);
    }
    $client = Zend_Gdata_AuthSub::getHttpClient($_SESSION[&#039;sessionToken&#039;]);
    return $client;
}

/**
 * Create a new instance of the service, redirecting the user
 * to the AuthSub server if necessary.
 */
$service = new Zend_Gdata_Photos(getAuthSubHttpClient());
</pre>


            <p class="para">
                Finally, an unauthenticated server can be created for use with public feeds:
            </p>

            <pre class="programlisting brush: php">
// Create an instance of the service using an unauthenticated HTTP client
$service = new Zend_Gdata_Photos();
</pre>

        </div>
    </div>

    <div class="section" id="zend.gdata.photos.queries"><div class="info"><h1 class="title">Understanding and Constructing Queries</h1></div>
        

        <p class="para">
            The primary method to request data from the service is by constructing a query. There
            are query classes for each of the following types:
        </p>

        <ul class="itemizedlist">
            <li class="listitem">
                <p class="para">
                    <b class="firstterm">User</b> is used to specify the user whose data is being
                    searched for, and is specified as a username. if no user is provided, &quot;default&quot;
                    will be used instead to indicate the currently authenticated user (if
                    authenticated).
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">Album</b> is used to specify the album which is being
                    searched for, and is specified as either an id, or an album name.
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">Photo</b> is used to specify the photo which is being
                    searched for, and is specified as an id.
                </p>
            </li>
        </ul>

        <p class="para">A new <span class="classname">UserQuery</span> can be constructed as followed:</p>

        <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$query = new Zend_Gdata_Photos_UserQuery();
$query-&gt;setUser(&quot;sample.user&quot;);
</pre>


        <p class="para">
            for each query, a number of parameters limiting the search can be requested, or
            specified, with get(Parameter) and set(Parameter), respectively. They are as follows:
        </p>

        <ul class="itemizedlist">
            <li class="listitem">
                <p class="para">
                    <b class="firstterm">Projection</b> sets the format of the data returned in the
                    feed, as either &quot;api&quot; or &quot;base&quot;. Normally, &quot;api&quot; is desired. The default is
                    &quot;api&quot;.
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">Type</b> sets the type of element to be returned, as either
                    &quot;feed&quot; or &quot;entry&quot;. The default is &quot;feed&quot;.
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">Access</b> sets the visibility of items to be returned, as
                    &quot;all&quot;, &quot;public&quot;, or &quot;private&quot;. The default is &quot;all&quot;. Non-public elements will
                    only be returned if the query is searching for the authenticated user.
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">Tag</b> sets a tag filter for returned items. When a tag is
                    set, only items tagged with this value will return.
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">Kind</b> sets the kind of elements to return. When kind is
                    specified, only entries that match this value will be returned.
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">ImgMax</b> sets the maximum image size for entries returned.
                    Only image entries smaller than this value will be returned.
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">Thumbsize</b> sets the thumbsize of entries that are
                    returned. Any retrieved entry will have a thumbsize equal to this value.
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">User</b> sets the user whose data is being searched for. The
                    default is &quot;default&quot;.
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">AlbumId</b> sets the id of the album being searched for. This
                    element only applies to album and photo queries. In the case of photo queries,
                    this specifies the album that contains the requested photo. The album id is
                    mutually exclusive with the album&#039;s name. Setting one unsets the other.
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">AlbumName</b> sets the name of the album being searched for.
                    This element only applies to the album and photo queries. In the case of photo
                    queries, this specifies the album that contains the requested photo. The album
                    name is mutually exclusive with the album&#039;s id. Setting one unsets the other.
                </p>
            </li>

            <li class="listitem">
                <p class="para">
                    <b class="firstterm">PhotoId</b> sets the id of the photo being searched for. This
                    element only applies to photo queries.
                </p>
            </li>
        </ul>
    </div>

    <div class="section" id="zend.gdata.photos.retrieval"><div class="info"><h1 class="title">Retrieving Feeds And Entries</h1></div>
        

        <p class="para">
            The service has functions to retrieve a feed, or individual entries, for users, albums,
            and individual photos.
        </p>

        <div class="section" id="zend.gdata.photos.user_retrieval"><div class="info"><h1 class="title">Retrieving A User</h1></div>
            

            <p class="para">
                The service supports retrieving a user feed and list of the user&#039;s content. If the
                requested user is also the authenticated user, entries marked as
                &quot;<em class="emphasis">hidden</em>&quot; will also be returned.
            </p>

            <p class="para">
                The user feed can be accessed by passing the username to the
                 <span class="methodname">getUserFeed()</span> method:
            </p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

try {
    $userFeed = $service-&gt;getUserFeed(&quot;sample.user&quot;);
} catch (Zend_Gdata_App_Exception $e) {
    echo &quot;Error: &quot; . $e-&gt;getMessage();
}
</pre>


            <p class="para">Or, the feed can be accessed by constructing a query, first:</p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$query = new Zend_Gdata_Photos_UserQuery();
$query-&gt;setUser(&quot;sample.user&quot;);

try {
    $userFeed = $service-&gt;getUserFeed(null, $query);
} catch (Zend_Gdata_App_Exception $e) {
    echo &quot;Error: &quot; . $e-&gt;getMessage();
}
</pre>


            <p class="para">
                Constructing a query also provides the ability to request a user entry object:
            </p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$query = new Zend_Gdata_Photos_UserQuery();
$query-&gt;setUser(&quot;sample.user&quot;);
$query-&gt;setType(&quot;entry&quot;);

try {
    $userEntry = $service-&gt;getUserEntry($query);
} catch (Zend_Gdata_App_Exception $e) {
    echo &quot;Error: &quot; . $e-&gt;getMessage();
}
</pre>

        </div>

        <div class="section" id="zend.gdata.photos.album_retrieval"><div class="info"><h1 class="title">Retrieving An Album</h1></div>
            

            <p class="para">
                The service supports retrieving an album feed and a list of the album&#039;s content.
            </p>

            <p class="para">
                The album feed is accessed by constructing a query object and passing it to
                 <span class="methodname">getAlbumFeed()</span>:
            </p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$query = new Zend_Gdata_Photos_AlbumQuery();
$query-&gt;setUser(&quot;sample.user&quot;);
$query-&gt;setAlbumId(&quot;1&quot;);

try {
    $albumFeed = $service-&gt;getAlbumFeed($query);
} catch (Zend_Gdata_App_Exception $e) {
    echo &quot;Error: &quot; . $e-&gt;getMessage();
}
</pre>


            <p class="para">
                Alternatively, the query object can be given an album name with
                 <span class="methodname">setAlbumName()</span>. Setting the album name is mutually
                exclusive with setting the album id, and setting one will unset the other.
            </p>

            <p class="para">
                Constructing a query also provides the ability to request an album entry object:
            </p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$query = new Zend_Gdata_Photos_AlbumQuery();
$query-&gt;setUser(&quot;sample.user&quot;);
$query-&gt;setAlbumId(&quot;1&quot;);
$query-&gt;setType(&quot;entry&quot;);

try {
    $albumEntry = $service-&gt;getAlbumEntry($query);
} catch (Zend_Gdata_App_Exception $e) {
    echo &quot;Error: &quot; . $e-&gt;getMessage();
}
</pre>

        </div>

        <div class="section" id="zend.gdata.photos.photo_retrieval"><div class="info"><h1 class="title">Retrieving A Photo</h1></div>
            

            <p class="para">
                The service supports retrieving a photo feed and a list of associated comments and
                tags.
            </p>

            <p class="para">
                The photo feed is accessed by constructing a query object and passing it to
                 <span class="methodname">getPhotoFeed()</span>:
            </p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$query = new Zend_Gdata_Photos_PhotoQuery();
$query-&gt;setUser(&quot;sample.user&quot;);
$query-&gt;setAlbumId(&quot;1&quot;);
$query-&gt;setPhotoId(&quot;100&quot;);

try {
    $photoFeed = $service-&gt;getPhotoFeed($query);
} catch (Zend_Gdata_App_Exception $e) {
    echo &quot;Error: &quot; . $e-&gt;getMessage();
}
</pre>


            <p class="para">
                Constructing a query also provides the ability to request a photo entry object:
            </p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$query = new Zend_Gdata_Photos_PhotoQuery();
$query-&gt;setUser(&quot;sample.user&quot;);
$query-&gt;setAlbumId(&quot;1&quot;);
$query-&gt;setPhotoId(&quot;100&quot;);
$query-&gt;setType(&quot;entry&quot;);

try {
    $photoEntry = $service-&gt;getPhotoEntry($query);
} catch (Zend_Gdata_App_Exception $e) {
    echo &quot;Error: &quot; . $e-&gt;getMessage();
}
</pre>

        </div>

        <div class="section" id="zend.gdata.photos.comment_retrieval"><div class="info"><h1 class="title">Retrieving A Comment</h1></div>
            

            <p class="para">
                The service supports retrieving comments from a feed of a different type. By setting
                a query to return a kind of &quot;comment&quot;, a feed request can return comments associated
                with a specific user, album, or photo.
            </p>

            <p class="para">
                Performing an action on each of the comments on a given photo can be accomplished
                as follows:
            </p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$query = new Zend_Gdata_Photos_PhotoQuery();
$query-&gt;setUser(&quot;sample.user&quot;);
$query-&gt;setAlbumId(&quot;1&quot;);
$query-&gt;setPhotoId(&quot;100&quot;);
$query-&gt;setKind(&quot;comment&quot;);

try {
    $photoFeed = $service-&gt;getPhotoFeed($query);

    foreach ($photoFeed as $entry) {
        if ($entry instanceof Zend_Gdata_Photos_CommentEntry) {
            // Do something with the comment
        }
    }
} catch (Zend_Gdata_App_Exception $e) {
    echo &quot;Error: &quot; . $e-&gt;getMessage();
}
</pre>

        </div>

        <div class="section" id="zend.gdata.photos.tag_retrieval"><div class="info"><h1 class="title">Retrieving A Tag</h1></div>
            

            <p class="para">
                The service supports retrieving tags from a feed of a different type. By setting a
                query to return a kind of &quot;tag&quot;, a feed request can return tags associated with a
                specific photo.
            </p>

            <p class="para">
                Performing an action on each of the tags on a given photo can be accomplished as
                follows:
            </p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$query = new Zend_Gdata_Photos_PhotoQuery();
$query-&gt;setUser(&quot;sample.user&quot;);
$query-&gt;setAlbumId(&quot;1&quot;);
$query-&gt;setPhotoId(&quot;100&quot;);
$query-&gt;setKind(&quot;tag&quot;);

try {
    $photoFeed = $service-&gt;getPhotoFeed($query);

    foreach ($photoFeed as $entry) {
        if ($entry instanceof Zend_Gdata_Photos_TagEntry) {
            // Do something with the tag
        }
    }
} catch (Zend_Gdata_App_Exception $e) {
    echo &quot;Error: &quot; . $e-&gt;getMessage();
}
</pre>

        </div>
    </div>

    <div class="section" id="zend.gdata.photos.creation"><div class="info"><h1 class="title">Creating Entries</h1></div>
        

        <p class="para">The service has functions to create albums, photos, comments, and tags.</p>

        <div class="section" id="zend.gdata.photos.album_creation"><div class="info"><h1 class="title">Creating An Album</h1></div>
            

            <p class="para">The service supports creating a new album for an authenticated user:</p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$entry = new Zend_Gdata_Photos_AlbumEntry();
$entry-&gt;setTitle($service-&gt;newTitle(&quot;test album&quot;));

$service-&gt;insertAlbumEntry($entry);
</pre>

        </div>

        <div class="section" id="zend.gdata.photos.photo_creation"><div class="info"><h1 class="title">Creating A Photo</h1></div>
            

            <p class="para">The service supports creating a new photo for an authenticated user:</p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

// $photo is the name of a file uploaded via an HTML form

$fd = $service-&gt;newMediaFileSource($photo[&quot;tmp_name&quot;]);
$fd-&gt;setContentType($photo[&quot;type&quot;]);

$entry = new Zend_Gdata_Photos_PhotoEntry();
$entry-&gt;setMediaSource($fd);
$entry-&gt;setTitle($service-&gt;newTitle($photo[&quot;name&quot;]));

$albumQuery = new Zend_Gdata_Photos_AlbumQuery;
$albumQuery-&gt;setUser(&quot;sample.user&quot;);
$albumQuery-&gt;setAlbumId(&quot;1&quot;);

$albumEntry = $service-&gt;getAlbumEntry($albumQuery);

$service-&gt;insertPhotoEntry($entry, $albumEntry);
</pre>

        </div>

        <div class="section" id="zend.gdata.photos.comment_creation"><div class="info"><h1 class="title">Creating A Comment</h1></div>
            

            <p class="para">The service supports creating a new comment for a photo:</p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$entry = new Zend_Gdata_Photos_CommentEntry();
$entry-&gt;setTitle($service-&gt;newTitle(&quot;comment&quot;));
$entry-&gt;setContent($service-&gt;newContent(&quot;comment&quot;));

$photoQuery = new Zend_Gdata_Photos_PhotoQuery;
$photoQuery-&gt;setUser(&quot;sample.user&quot;);
$photoQuery-&gt;setAlbumId(&quot;1&quot;);
$photoQuery-&gt;setPhotoId(&quot;100&quot;);
$photoQuery-&gt;setType(&#039;entry&#039;);

$photoEntry = $service-&gt;getPhotoEntry($photoQuery);

$service-&gt;insertCommentEntry($entry, $photoEntry);
</pre>

        </div>

        <div class="section" id="zend.gdata.photos.tag_creation"><div class="info"><h1 class="title">Creating A Tag</h1></div>
            

            <p class="para">The service supports creating a new tag for a photo:</p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$entry = new Zend_Gdata_Photos_TagEntry();
$entry-&gt;setTitle($service-&gt;newTitle(&quot;tag&quot;));

$photoQuery = new Zend_Gdata_Photos_PhotoQuery;
$photoQuery-&gt;setUser(&quot;sample.user&quot;);
$photoQuery-&gt;setAlbumId(&quot;1&quot;);
$photoQuery-&gt;setPhotoId(&quot;100&quot;);
$photoQuery-&gt;setType(&#039;entry&#039;);

$photoEntry = $service-&gt;getPhotoEntry($photoQuery);

$service-&gt;insertTagEntry($entry, $photoEntry);
</pre>

        </div>
    </div>

    <div class="section" id="zend.gdata.photos.deletion"><div class="info"><h1 class="title">Deleting Entries</h1></div>
        

        <p class="para">The service has functions to delete albums, photos, comments, and tags.</p>

        <div class="section" id="zend.gdata.photos.album_deletion"><div class="info"><h1 class="title">Deleting An Album</h1></div>
            

            <p class="para">The service supports deleting an album for an authenticated user:</p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$albumQuery = new Zend_Gdata_Photos_AlbumQuery;
$albumQuery-&gt;setUser(&quot;sample.user&quot;);
$albumQuery-&gt;setAlbumId(&quot;1&quot;);
$albumQuery-&gt;setType(&#039;entry&#039;);

$entry = $service-&gt;getAlbumEntry($albumQuery);

$service-&gt;deleteAlbumEntry($entry, true);
</pre>

        </div>

        <div class="section" id="zend.gdata.photos.photo_deletion"><div class="info"><h1 class="title">Deleting A Photo</h1></div>
            

            <p class="para">The service supports deleting a photo for an authenticated user:</p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$photoQuery = new Zend_Gdata_Photos_PhotoQuery;
$photoQuery-&gt;setUser(&quot;sample.user&quot;);
$photoQuery-&gt;setAlbumId(&quot;1&quot;);
$photoQuery-&gt;setPhotoId(&quot;100&quot;);
$photoQuery-&gt;setType(&#039;entry&#039;);

$entry = $service-&gt;getPhotoEntry($photoQuery);

$service-&gt;deletePhotoEntry($entry, true);
</pre>

        </div>

        <div class="section" id="zend.gdata.photos.comment_deletion"><div class="info"><h1 class="title">Deleting A Comment</h1></div>
            

            <p class="para">The service supports deleting a comment for an authenticated user:</p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$photoQuery = new Zend_Gdata_Photos_PhotoQuery;
$photoQuery-&gt;setUser(&quot;sample.user&quot;);
$photoQuery-&gt;setAlbumId(&quot;1&quot;);
$photoQuery-&gt;setPhotoId(&quot;100&quot;);
$photoQuery-&gt;setType(&#039;entry&#039;);

$path = $photoQuery-&gt;getQueryUrl() . &#039;/commentid/&#039; . &quot;1000&quot;;

$entry = $service-&gt;getCommentEntry($path);

$service-&gt;deleteCommentEntry($entry, true);
</pre>

        </div>

        <div class="section" id="zend.gdata.photos.tag_deletion"><div class="info"><h1 class="title">Deleting A Tag</h1></div>
            

            <p class="para">The service supports deleting a tag for an authenticated user:</p>

            <pre class="programlisting brush: php">
$service = Zend_Gdata_Photos::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Photos($client);

$photoQuery = new Zend_Gdata_Photos_PhotoQuery;
$photoQuery-&gt;setUser(&quot;sample.user&quot;);
$photoQuery-&gt;setAlbumId(&quot;1&quot;);
$photoQuery-&gt;setPhotoId(&quot;100&quot;);
$photoQuery-&gt;setKind(&quot;tag&quot;);
$query = $photoQuery-&gt;getQueryUrl();

$photoFeed = $service-&gt;getPhotoFeed($query);

foreach ($photoFeed as $entry) {
    if ($entry instanceof Zend_Gdata_Photos_TagEntry) {
        if ($entry-&gt;getContent() == $tagContent) {
            $tagEntry = $entry;
        }
    }
}

$service-&gt;deleteTagEntry($tagEntry, true);
</pre>

        </div>

        <div class="section" id="zend.gdata.photos.optimistic_concurrenty"><div class="info"><h1 class="title">Optimistic Concurrency (Notes On Deletion)</h1></div>
            

            <p class="para">
                GData feeds, including those of the Picasa Web Albums service, implement optimistic
                concurrency, a versioning system that prevents users from overwriting changes,
                inadvertently. When deleting a entry through the service class, if the entry has
                been modified since it was last fetched, an exception will be thrown, unless
                explicitly set otherwise (in which case the deletion is retried on the updated
                entry).
            </p>

            <p class="para">
                An example of how to handle versioning during a deletion is shown by
                 <span class="methodname">deleteAlbumEntry()</span>:
            </p>

            <pre class="programlisting brush: php">
// $album is the albumEntry to be deleted
try {
    $this-&gt;delete($album);
} catch (Zend_Gdata_App_HttpException $e) {
    if ($e-&gt;getMessage()-&gt;getStatus() === 409) {
        $entry =
            new Zend_Gdata_Photos_AlbumEntry($e-&gt;getMessage()-&gt;getBody());
        $this-&gt;delete($entry-&gt;getLink(&#039;edit&#039;)-&gt;href);
    } else {
        throw $e;
    }
}
</pre>

        </div>
    </div>
</div>
        <hr />

            <table width="100%">
                <tr>
                    <td width="25%" style="text-align: left;">
                    <a href="zend.gdata.gbase.html">Using Google Base</a>
                    </td>

                    <td width="50%" style="text-align: center;">
                        <div class="up"><span class="up"><a href="zend.gdata.html">Zend_Gdata</a></span><br />
                        <span class="home"><a href="manual.html">Programmer's Reference Guide</a></span></div>
                    </td>

                    <td width="25%" style="text-align: right;">
                        <div class="next" style="text-align: right; float: right;"><a href="zend.gdata.youtube.html">Using the YouTube Data API</a></div>
                    </td>
                </tr>
            </table>
</td>
        <td style="font-size: smaller;" width="15%"> <style type="text/css">
#leftbar {
	float: left;
	width: 186px;
	padding: 5px;
	font-size: smaller;
}
ul.toc {
	margin: 0px 5px 5px 5px;
	padding: 0px;
}
ul.toc li {
	font-size: 85%;
	margin: 1px 0 1px 1px;
	padding: 1px 0 1px 11px;
	list-style-type: none;
	background-repeat: no-repeat;
	background-position: center left;
}
ul.toc li.header {
	font-size: 115%;
	padding: 5px 0px 5px 11px;
	border-bottom: 1px solid #cccccc;
	margin-bottom: 5px;
}
ul.toc li.active {
	font-weight: bold;
}
ul.toc li a {
	text-decoration: none;
}
ul.toc li a:hover {
	text-decoration: underline;
}
</style>
 <ul class="toc">
  <li class="header home"><a href="manual.html">Programmer's Reference Guide</a></li>
  <li class="header up"><a href="manual.html">Programmer's Reference Guide</a></li>
  <li class="header up"><a href="reference.html">Zend Framework Reference</a></li>
  <li class="header up"><a href="zend.gdata.html">Zend_Gdata</a></li>
  <li><a href="zend.gdata.introduction.html">Introduction</a></li>
  <li><a href="zend.gdata.authsub.html">Authenticating with AuthSub</a></li>
  <li><a href="zend.gdata.books.html">Using the Book Search Data API</a></li>
  <li><a href="zend.gdata.clientlogin.html">Authenticating with ClientLogin</a></li>
  <li><a href="zend.gdata.calendar.html">Using Google Calendar</a></li>
  <li><a href="zend.gdata.docs.html">Using Google Documents List Data API</a></li>
  <li><a href="zend.gdata.health.html">Using Google Health</a></li>
  <li><a href="zend.gdata.spreadsheets.html">Using Google Spreadsheets</a></li>
  <li><a href="zend.gdata.gapps.html">Using Google Apps Provisioning</a></li>
  <li><a href="zend.gdata.gbase.html">Using Google Base</a></li>
  <li class="active"><a href="zend.gdata.photos.html">Using Picasa Web Albums</a></li>
  <li><a href="zend.gdata.youtube.html">Using the YouTube Data API</a></li>
  <li><a href="zend.gdata.exception.html">Catching Gdata Exceptions</a></li>
 </ul>
 </td>
    </tr>
</table>

<script type="text/javascript" src="../js/shCore.js"></script>
<script type="text/javascript" src="../js/shAutoloader.js"></script>
<script type="text/javascript" src="../js/main.js"></script>

</body>
</html>